package com.qqls.youxiangousys.pj.sys.service.impl;
import com.qqls.youxiangousys.pj.common.annotation.RequiredLog;
import com.qqls.youxiangousys.pj.common.entity.Pagination;
import com.qqls.youxiangousys.pj.common.util.Assert;
import com.qqls.youxiangousys.pj.sys.dao.SysRoleDao;
import com.qqls.youxiangousys.pj.sys.dao.SysRoleMenuDao;
import com.qqls.youxiangousys.pj.sys.dao.SysUserRoleDao;
import com.qqls.youxiangousys.pj.sys.entity.SaveExcelRoleObj;
import com.qqls.youxiangousys.pj.sys.entity.SysRole;
import com.qqls.youxiangousys.pj.sys.service.SysRoleService;
import com.qqls.youxiangousys.pj.sys.vo.SysRoleMenuVO;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleDao roleDao;

    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    public List<SysRole> findAllRole() {
        List<SysRole> list = roleDao.findAllRole();
        return list;
    }

    /**
     * 初始加载分页数据
     * @param name
     * @param curPage
     * @param pageSize
     * @return
     */
    @RequiredLog("查询角色")
    public Pagination findRole(String name, Integer curPage, Integer pageSize) {
        //1.验证curPage,pageSzie是否有值
        Assert.isEmpty(curPage == null || pageSize == null, "请选择当前页马或每页条数");
        //2.得到角色的总条数
        int count = roleDao.countRole(name);
        //3.创建分页对象，算出所有属性
        Pagination pageObj = new Pagination(curPage, count, pageSize);
        curPage = pageObj.getCurPage();//得到当前页
        pageSize = pageObj.getPageSize();//得到每页条数
        int start = (curPage -1 ) * pageSize;//分页跳过多少条=(当前页 - 1 ) * 每页条数
        //4.根据参数找角色
        List<SysRole> list = roleDao.findRole(name, start,pageSize);
        //5.验证第4步的结果是否为null
        Assert.isEmpty(list == null || list.size() == 0, "数据或已被删除");
        pageObj.setPageData(list);//设置分页数据
        return pageObj;
    }

    /**
     * 添加角色，角色需要授权
     * @param role
     * @param ids
     * @return
     */
    @RequiredLog("添加角色")
    public Integer insertRole(SysRole role, Integer[] ids) {
        //1.验证参数
        Assert.isEmpty(role == null || role.getName() == null || role.getName().equals(""),"不允许为空");
        Assert.isEmpty(ids == null || ids.length == 0 ,"必须为角色分配权限");
        //2.插入角色
        int n = roleDao.insertRole(role);
        //3.验证结果
        Assert.isEmpty(n == 0, "插入失败");
        //4.插入角色和菜单关系数据
        int m = sysRoleMenuDao.insertRoleMenu(role.getId(), ids);
        //5.验证结果
        Assert.isEmpty(m == 0, "插入失败");
        return n;
    }

    /**
     * 修改角色
     * @param vo
     * @return
     */
    @RequiredLog("修改角色")
    public Integer updateRoleById(SysRoleMenuVO vo) {
        Assert.isEmpty(vo == null || vo.getId()==null, "请选择要修改角色");
        //根据角色id修改角色菜单关系数据
        //int n = rmdao.updateRoleMenuByRoleId(vo.getId(),vo.getMenuIds());
        //根据角色id删除角色菜单数据
        sysRoleMenuDao.deleteRoleMenuByMenuId(vo.getId());
        sysRoleMenuDao.insertRoleMenu(vo.getId(), vo.getMenuIds().toArray(new Integer[] {}));
        int n = roleDao.updateRoleById(vo);
        Assert.isEmpty(n == 0, "修改失败");
        return n;
    }

    /**
     * 通过角色id找角色和角色的菜单id
     * @param id
     * @return
     */
    public SysRoleMenuVO findRoleMenuIds(Integer id) {
        //验证参数
        Assert.isEmpty(id == null || id == 0, "请选择修改的角色");
        SysRoleMenuVO vo =	roleDao.findRoleMenuIds(id);
        Assert.isEmpty(vo == null , "角色不存在或已被删除");
        return vo;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @RequiredLog("删除角色")
    public Integer deleteRoleById(Integer id) {
        //1.验证参数
        Assert.isEmpty(id==null || id==0, "请选择");
        //2.调用三个dao的与角色相关的删除方法
        int n = roleDao.deleteRoleById(id);
        sysRoleMenuDao.deleteRoleMenuByRoleId(id);
        sysUserRoleDao.deleteRoleMenuByRoleId(id);
        Assert.isEmpty(n==0, "已删除!");
        //3.验证结果
        return n;
    }

    /**
     * 导出所有
     */
    @RequiredLog("导出所有角色")
    public void exportAll() {
        //创建XSSFWorkbook对象
        @SuppressWarnings("resource")
        Workbook wookbook = new XSSFWorkbook();
        //创建一个sheet
        Sheet sheet = wookbook.createSheet("角色数据详情表");
        //创建行，从0开始
        Row row = sheet.createRow(0);
        //处理表头
        handlerRowTitle(row);
        List<SysRole> list = roleDao.findAllCar();
        for (int i = 0;i < list.size();i ++ ){
            Row rowRole = sheet.createRow(i + 1);
            //把每一个汽车信息对象写入行中
            handlerRowCar(rowRole, list.get(i));
        }
        try (FileOutputStream fos = new FileOutputStream("D:/role.xlsx");){
            wookbook.write(fos);//把文件写出到指定路径
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 导入
     * @param file
     * @return
     */
    @SuppressWarnings("unchecked")
    @RequiredLog("导入所有角色")
    public SaveExcelRoleObj handlerSaveExportRole(MultipartFile file) {
        SaveExcelRoleObj ser = new SaveExcelRoleObj();
        try{
            InputStream is = file.getInputStream();//获取文件输入流
            Map<String, List<?>> map = getListRoleExcel(is);
            int n = roleDao.insertCarExcel((List<SysRole>) map.get("roleData"));
            Assert.isEmpty(n == 0,"数据导入失败或无数据");
            ser.setSuccessNumber(n);
            ser.setErrorNumber((List<Integer>) map.get("numList"));
        }catch (Exception e){
            e.printStackTrace();
        }
        return ser;
    }

    private Map<String, List<?>> getListRoleExcel(InputStream is) throws Exception {
        List<SysRole> list = new ArrayList<>();
        List<Integer> numList = new ArrayList<>();
        //获取WorkBook对象
        @SuppressWarnings("resource")
        Workbook workBook = new XSSFWorkbook(is);
        //获取有效sheet的数量
        int number = workBook.getNumberOfSheets();
        for (int i = 0; i < number; i++) {
            //获取Sheet对象
            Sheet sheet = workBook.getSheetAt(i);
            if (sheet == null) {//sheet表为空则跳过
                continue;
            }
            //获取初始行号
            int startRow = sheet.getFirstRowNum();
            //获取结束行号
            int endRow = sheet.getLastRowNum();
            for (int j = startRow + 1; j <= endRow; j++) {
                Row row = sheet.getRow(j);//获取行
                Cell cell0 = row.getCell(0);
                //getNumericCellValue()获取数字
                int id = (int) cell0.getNumericCellValue();
                Cell cell1 = row.getCell(1);
                String name = cell1.getStringCellValue();
                Cell cell2 = row.getCell(2);
                String remarks = cell2.getStringCellValue();
                Cell cell3 = row.getCell(3);
                Date creationTime = cell3.getDateCellValue();
                Cell cell4 = row.getCell(4);
                Date modificationTime = cell4.getDateCellValue();
                Cell cell5 = row.getCell(5);
                String createuser = cell5.getStringCellValue();
                Cell cell6 = row.getCell(6);
                String updateuser = cell6.getStringCellValue();
                SysRole role = new SysRole(id,name,remarks,creationTime,modificationTime,createuser,updateuser);
                SysRole sr = roleDao.finCarByTypePrice(name, remarks);
                if (sr == null && !list.contains(role)) {
                    list.add(role);
                } else {
                    numList.add(j+1);
                }
            }
        }
        Map<String, List<?>> map = new HashMap<>();
        map.put("roleData", list);
        map.put("numList", numList);
        return map;
    }

    private void handlerRowCar(Row rowRole, SysRole role) {
        Cell cell0 = rowRole.createCell(0);
        cell0.setCellValue(rowRole.getRowNum());//id
        Cell cell1 = rowRole.createCell(1);
        cell1.setCellValue(role.getName());//角色名称
        Cell cell2 = rowRole.createCell(2);
        cell2.setCellValue(role.getRemarks());//备注
        Cell cell3 = rowRole.createCell(3);
        cell3.setCellValue(role.getCreationTime());//创建时间
        Cell cell4 = rowRole.createCell(4);
        cell4.setCellValue(role.getModificationTime());//修改时间
        Cell cell5 = rowRole.createCell(5);
        cell5.setCellValue(role.getCreateUser());//创建用户
        Cell cell6 = rowRole.createCell(6);
        cell6.setCellValue(role.getUpdateUser());//修改用户
    }

    private void handlerRowTitle(Row row) {
        String [] titles = {"id", "角色名称", "备注", "创建时间","修改时间", "创建用户", "修改用户"};
        for (int i = 0; i < titles.length; i++) {
            //创建一个单元格
            Cell cell = row.createCell(i);
            //设置单元格的值
            cell.setCellValue(titles[i]);
        }
    }
}
